`<template>
  <div class="container p-4 mx-auto">
    <h1 class="mb-4 text-2xl font-bold">正则表达式可视化</h1>
    
    <div class="space-y-4">
      <!-- 正则输入 -->
      <div class="space-y-2">
        <label class="block text-sm font-medium">正则表达式:</label>
        <div class="flex gap-2">
          <input
            v-model="regex"
            type="text"
            class="flex-1 p-2 font-mono border rounded-lg"
            placeholder="输入正则表达式，如: ^[a-z]+$"
          />
          <select v-model="flags" class="p-2 border rounded-lg">
            <option value="">无标志</option>
            <option value="g">g (全局)</option>
            <option value="i">i (忽略大小写)</option>
            <option value="gi">gi (全局+忽略大小写)</option>
          </select>
        </div>
      </div>

      <!-- 测试文本 -->
      <div class="space-y-2">
        <label class="block text-sm font-medium">测试文本:</label>
        <textarea
          v-model="testText"
          class="w-full h-32 p-2 font-mono border rounded-lg"
          placeholder="输入要测试的文本..."
        ></textarea>
      </div>

      <!-- 可视化结果 -->
      <div v-if="regex" class="space-y-4">
        <h2 class="text-xl font-semibold">匹配结果:</h2>
        
        <!-- 语法解释 -->
        <div class="p-4 border rounded-lg">
          <h3 class="mb-2 font-medium">正则表达式解释:</h3>
          <div class="space-y-2">
            <div v-for="(part, index) in regexParts" :key="index" class="flex items-start gap-2">
              <span class="px-2 py-1 font-mono bg-gray-100 rounded">{{ part.pattern }}</span>
              <span class="text-gray-600">{{ part.explanation }}</span>
            </div>
          </div>
        </div>

        <!-- 匹配高亮 -->
        <div class="p-4 border rounded-lg">
          <h3 class="mb-2 font-medium">匹配高亮:</h3>
          <div class="font-mono whitespace-pre-wrap">
            <template v-for="(part, index) in highlightedText" :key="index">
              <span
                :class="{
                  'bg-green-200': part.isMatch,
                  'text-gray-800': !part.isMatch
                }"
              >{{ part.text }}</span>
            </template>
          </div>
        </div>

        <!-- 匹配组信息 -->
        <div v-if="matchGroups.length > 0" class="p-4 border rounded-lg">
          <h3 class="mb-2 font-medium">捕获组:</h3>
          <div class="space-y-2">
            <div v-for="(group, index) in matchGroups" :key="index" class="flex items-center gap-2">
              <span class="px-2 py-1 font-mono bg-gray-100 rounded">组 {{ index }}</span>
              <span class="font-mono text-green-600">{{ group }}</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'

const regex = ref('')
const flags = ref('')
const testText = ref('')

// 解析正则表达式各部分
const regexParts = computed(() => {
  if (!regex.value) return []
  
  const parts = []
  let currentRegex = regex.value

  // 常见正则模式的解释
  const patterns = [
    { pattern: '^', explanation: '匹配行首' },
    { pattern: '$', explanation: '匹配行尾' },
    { pattern: '\\d', explanation: '匹配任意数字' },
    { pattern: '\\w', explanation: '匹配字母、数字或下划线' },
    { pattern: '\\s', explanation: '匹配任意空白字符' },
    { pattern: '[a-z]', explanation: '匹配小写字母' },
    { pattern: '[A-Z]', explanation: '匹配大写字母' },
    { pattern: '[0-9]', explanation: '匹配数字' },
    { pattern: '+', explanation: '匹配前面的模式一次或多次' },
    { pattern: '*', explanation: '匹配前面的模式零次或多次' },
    { pattern: '?', explanation: '匹配前面的模式零次或一次' },
    { pattern: '{n}', explanation: '精确匹配n次' },
    { pattern: '{n,}', explanation: '匹配至少n次' },
    { pattern: '{n,m}', explanation: '匹配n到m次' }
  ]

  // 尝试匹配每个模式
  patterns.forEach(({ pattern, explanation }) => {
    if (currentRegex.includes(pattern)) {
      parts.push({ pattern, explanation })
      currentRegex = currentRegex.replace(pattern, '')
    }
  })

  return parts
})

// 高亮匹配文本
const highlightedText = computed(() => {
  if (!regex.value || !testText.value) return [{ text: testText.value, isMatch: false }]

  try {
    const re = new RegExp(regex.value, flags.value)
    const parts = []
    let lastIndex = 0

    testText.value.replace(re, (match, ...args) => {
      const offset = args[args.length - 2]
      
      // 添加非匹配部分
      if (offset > lastIndex) {
        parts.push({
          text: testText.value.slice(lastIndex, offset),
          isMatch: false
        })
      }

      // 添加匹配部分
      parts.push({
        text: match,
        isMatch: true
      })

      lastIndex = offset + match.length
      return match
    })

    // 添加剩余的非匹配部分
    if (lastIndex < testText.value.length) {
      parts.push({
        text: testText.value.slice(lastIndex),
        isMatch: false
      })
    }

    return parts.length ? parts : [{ text: testText.value, isMatch: false }]
  } catch (e) {
    return [{ text: testText.value, isMatch: false }]
  }
})

// 获取匹配组
const matchGroups = computed(() => {
  if (!regex.value || !testText.value) return []

  try {
    const re = new RegExp(regex.value, flags.value)
    const match = testText.value.match(re)
    return match ? match : []
  } catch (e) {
    return []
  }
})
</script>`